%%%-------------------------------------------------------------------
%%% @author mirahs(2892727493@qq.com)
%%% @doc
%%%     角色扩展数据
%%% @end
%%%-------------------------------------------------------------------
-module(role_ext_parse).

-export([init_role_ext/0, parse/1, to_role_ext/1, to_role/2]).

-export([get_ver/1, get_ver_index/0, validate/1, get_field_parse/0, process_after/1]).

-include("common.hrl").
-include("role.hrl").
-include("role_data.hrl").
-include("parse.hrl").


%%%===================================================================
%%% 配置
%%%===================================================================

parse_config() ->
    [
        % role 结构位置           role_ext 结构位置            解析器           初始值
        {#role.date_reset,      #role_ext.date_reset,       undefined,      undefined}
    ].


%%%===================================================================
%%% API functions
%%%===================================================================

%% 初始化 role_ext
init_role_ext() ->
    RoleExt = #role_ext{},
    lists:foldl(fun({_, RoleExtPos, _, InitVal}, Acc) -> erlang:setelement(RoleExtPos, Acc, InitVal) end, RoleExt, parse_config()).

%% 解析 role_ext
parse(Data) ->
    parse:parse(?MODULE, Data).


%% 处理不能被保存的pid和一些不想保存的数据
do_save_before(Role) ->
    Role.

%% 将role转换成role_ext
to_role_ext(Role) ->
    NewRole = do_save_before(Role),
    RoleExt = #role_ext{},
    Nr2 = lists:foldl(fun({RolePos, RoleExtPos, _, _}, Acc) ->
        Data = erlang:element(RolePos, NewRole),
        erlang:setelement(RoleExtPos, Acc, Data)
                      end, RoleExt, parse_config()),
    {ok, Nr2}.

%% 将 role_ext 转换成 role
to_role(Role, RoleExt0) ->
    case parse(RoleExt0) of
        {ok, RoleExt} ->
            Fun = fun
                      ({RolePos, RoleExtPos, _, _}, Acc) ->
                          Val = erlang:element(RoleExtPos, RoleExt),
                          erlang:setelement(RolePos, Acc, Val)
                  end,
            Nr = lists:foldl(Fun, Role, parse_config()),
            {ok, Nr};
        {false, Reason} ->
            {error, Reason}
    end.


%%%===================================================================
%%% parse behaviour
%%%===================================================================

%% @spec get_ver_index() -> integer()
%% 返回版本号的索引
get_ver_index() ->
    #role_ext.ver.

%% @spec validate(Data) -> true | false
%% Data = tuple()
%% 检测数据的正确性
validate(Data) ->
    is_record(Data, role_ext).

%% @spec get_field_parse() -> list()
%% 返回子元素的解析
get_field_parse() ->
    L = lists:map(fun
                      ({_, RoleExtPos, {list, Parser}, _}) -> {RoleExtPos, Parser, list};
                      ({_, RoleExtPos, Parser, _}) -> {RoleExtPos, Parser}
                  end, parse_config()),
    lists:filter(fun
                     ({_, undefined}) -> false;
                     ({_, undefined, _}) -> false;
                     (_) -> true
                 end, L).

%% @spec process_after(Data) -> NewData
%% Data = NewData = tuple()
%% 解析后的数据再处理
process_after(Data) ->
    {ok, Data}.

%% get_ver(Ver) -> ok | #parse_ver{}
%% Ver = integer()
%% 返回每个版本的变动，最终版本返回ok
get_ver(?role_ext_ver) ->
    ok.
